﻿using System;
using System.Collections.Generic;
using Omniscient.Foundation.Contrib.Data.MySql;
using Omniscient.Foundation.Data;
using MySql.Data.MySqlClient;
using Omniscient.Foundation.ApplicationModel;

namespace Omniscient.TimeTracker.Data.Adapters.MySql
{
    public class ClientAdapter : IEntityAdapter<Client>
    {
        IConnectivity _connectivity;

        public ClientAdapter() : this(ApplicationManager.Current.ServiceProvider.GetService<IConnectivity>()) { }

        public ClientAdapter(IConnectivity connectivity)
        {
            if (connectivity == null) throw new ArgumentNullException("The adapter cannot work with no connectivity.  Null argument: connectivity.");
            _connectivity = connectivity;
        }

        #region IEntityAdapter<Client> Members

        public EntityList<Client> LoadByObjectQuery(Omniscient.Foundation.Data.ObjectQuery.OQuery<Client> query)
        {
            throw new NotImplementedException("Not implemented yet.");
        }

        public Client LoadByKey(Guid id)
        {
            MySqlConnection cn;
            MySqlCommand cmd;
            MySqlDataReader rd;

            cn = _connectivity.CreateConnection();

            string sql = string.Format(@"SELECT CompanyName, ContactName, Description 
                            FROM client
                            WHERE ClientGuid = '{0}'", id.ToString("D"));

            try
            {
                cmd = cn.CreateCommand();
                cmd.CommandText = sql;
                cn.Open();
                rd = cmd.ExecuteReader();
                while (rd.Read())
                {
                    Client c;
                    c = new Client(id, true);
                    c.CompanyName = rd.GetString("CompanyName");
                    c.ContactName = rd.GetString("ContactName");
                    c.Description = rd.GetString("Description");
                    rd.Close();
                    return c;
                }
                return null;
            }
            finally
            {
                cn.Dispose();
            }
        }

        public void Save(Client entity)
        {
            string sql;
            MySqlConnection cn;
            MySqlCommand cmd;

            switch (entity.Status)
            {
                case EntityStatus.Dirty:
                    sql =
                        string.Format(
                        @"UPDATE client
                        set CompanyName = '{1}',
                        ContactName = '{2}',
                        Description = '{3}' 
                        WHERE ClientGuid = '{0}' ", entity.Id, entity.CompanyName, entity.ContactName, entity.Description);
                    break;
                case EntityStatus.New:
                    sql =
                        string.Format(
                        @"INSERT INTO client (ClientGuid, CompanyName, ContactName, Description)
                        VALUES ('{0}', '{1}', '{2}', '{3}')", entity.Id, entity.CompanyName, entity.ContactName, entity.Description);
                    break;
                case EntityStatus.ToBeDeleted:
                    sql = string.Format("DELETE FROM client WHERE ClientGuid = '{0}'", entity.Id);
                    break;
                default:
                    return;
            }

            cn = _connectivity.CreateConnection();

            try
            {
                cmd = cn.CreateCommand();
                cmd.CommandText = sql;
                cn.Open();
                int n = cmd.ExecuteNonQuery();
                if (n < 1) throw new InvalidOperationException("The query has affected no record in the database.");
                if (n > 1) throw new InvalidOperationException("the query has affected more than one record in the database.");
            }
            finally
            {
                cn.Dispose();
            }

        }

        public EntityList<Client> LoadAll()
        {
            MySqlConnection cn;
            MySqlCommand cmd;
            MySqlDataReader rd;
            EntityList<Client> clients;

            clients = new EntityList<Client>();
            cn = _connectivity.CreateConnection();

            string sql = @"SELECT ClientGuid, CompanyName, ContactName, Description FROM client";

            try
            {
                cmd = cn.CreateCommand();
                cmd.CommandText = sql;
                cn.Open();
                rd = cmd.ExecuteReader();
                while (rd.Read())
                {
                    Client c;
                    Guid id;
                    id = new Guid(rd.GetString("ClientGuid"));
                    c = new Client(id, true);
                    c.CompanyName = rd.GetString("CompanyName");
                    c.ContactName = rd.GetString("ContactName");
                    c.Description = rd.GetString("Description");
                    clients.Add(c);
                }
                rd.Close();
                return clients;
            }
            finally
            {
                cn.Dispose();
            }
        }

        public EntityList<Client> LoadByForeignKey(string propertyName, Guid id)
        {
            throw new NotImplementedException();
        }

        public EntityList<Client> LoadByQuery(string queryName)
        {
            throw new NotImplementedException();
        }

        public EntityList<Client> LoadByValueProperty(string propertyName, object value)
        {
            throw new NotImplementedException();
        }

        public void Save(IEnumerable<Client> entities)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}
